package com.profgj.profgj.controller;

import com.profgj.profgj.entity.*;
import com.profgj.profgj.enums.ServerStatus;
import com.profgj.profgj.service.*;
import com.profgj.profgj.utils.EmptyUtils;
import com.profgj.profgj.utils.ReturnOperator;
import com.profgj.profgj.vo.EmptyObject;
import com.profgj.profgj.vo.ResultMsg;
import io.swagger.annotations.*;
import org.apache.commons.io.FileUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import springfox.documentation.annotations.ApiIgnore;
import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;


/**
 * (级联添加)控制层
 *
 * @author 杨帅
 * @since 2021-06-22 11:09:35
 */

/**
 * JSON格式返回
 */
@RestController
/**
 * 请求基路径
 */
@RequestMapping("/cas")
@Api(tags = {"级联添加接口"}, description = "企业信息,项目信息,项目要件,产品能耗信息集合添加")
public class CascadeController {

    /**
     * 临时文件名
     */
    private static String tempfilename;

    /**
     * 临时文件数组
     */
    private static String[] tempfilenames;

    /**
     * 返回空对象的替代元素
     */
    private EmptyObject emptyObject = new EmptyObject();
    /**
     * 企业服务对象
     */
    @Resource
    private EnterpriseService enterpriseService;

    /**
     * 项目基本信息服务对象
     */
    @Resource
    private ProjectBaseInfoService projectBaseInfoService;

    /**
     * 项目要件服务对象
     */
    @Resource
    private ProjectImportantDocumentService projectImportantDocumentService;

    /**
     * 产品月能耗对象
     */
    @Resource
    private ProductMonthEnergyconsumptionService productMonthEnergyconsumptionService;

    /**
     * 产品对象
     */
    @Resource
    private ProductService productService;

    /**
     * 上传票据服务对象
     */
    @Resource
    private BillService billService;

    /**
     * 级联添加对数据进行添加
     * @return
     */
    @PostMapping("/cascade/add")
    @ApiOperation(value = "级联添加",produces = "application/json")
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public ResponseEntity<ResultMsg> cascadeAddMethod(@RequestBody Enterprise enterprise,
                                                      @RequestBody ProjectBaseInfo projectBaseInfo,
                                                      @RequestBody Bill bill,
                                                      @RequestBody ProjectImportantDocument projectImportantDocument,
                                                      @RequestBody Product product,
                                                      @RequestBody ProductMonthEnergyconsumption productMonthEnergyconsumption,
                                                      @ApiIgnore HttpSession session){
        // 参数对象校验
        if (!EmptyUtils.isEnterpriseEmpty(enterprise)) {
            return ReturnOperator.createResultMsg("", ServerStatus.ENTERPRISE_NOT_NUL, ServerStatus.ERROR,
                    new ArrayList<>(), emptyObject, HttpStatus.OK);
        }
        if (!EmptyUtils.isProjectBaseInfoEmpty(projectBaseInfo)) {
            return ReturnOperator.createResultMsg("", ServerStatus.PROJECTBASEINFO_NOT_NUL, ServerStatus.ERROR,
                    new ArrayList<>(), emptyObject, HttpStatus.OK);
        }
        if (!EmptyUtils.isProjectImportantDocumentEmpty(projectImportantDocument)) {
            return ReturnOperator.createResultMsg("", ServerStatus.PROJECTIMPORTANTDOCUMENT_NOT_NUL, ServerStatus.ERROR,
                    new ArrayList<>(), emptyObject, HttpStatus.OK);
        }
        if (!EmptyUtils.isProductEmpty(product)) {
            return ReturnOperator.createResultMsg("", ServerStatus.PRODUCT_NOT_NUL, ServerStatus.ERROR,
                    new ArrayList<>(), emptyObject, HttpStatus.OK);
        }
        if (!EmptyUtils.isProductMonthEnergyconsumptionEmpty(productMonthEnergyconsumption)) {
            return ReturnOperator.createResultMsg("", ServerStatus.PRODUCTENERGYCONSUMPTIONSITUATIONSUB_NOT_NUL, ServerStatus.ERROR,
                    new ArrayList<>(), emptyObject, HttpStatus.OK);
        }

        // 取得当前登录的用户角色id
        Integer role_id = Integer.valueOf(String.valueOf(session.getAttribute("role_id")));
        // 取得当前登录的用户id
        Integer user_id = Integer.valueOf(String.valueOf(session.getAttribute("user_id")));

        // 关键字查询企业 存在返回
        Enterprise enterprise_q = enterpriseService.queryByWord(enterprise.getEnName());
        // 检查企业是否已经存在
        if (EmptyUtils.isEnterpriseEmpty(enterprise_q)) {
            return ReturnOperator.createResultMsg("", ServerStatus.EN_EXISTS, ServerStatus.ERROR,
                    new ArrayList<>(), emptyObject, HttpStatus.OK);
        }

        // 不是管理员的情况下
        if (role_id != 1) {

            // 设置关联企业用户id
            enterprise.setEnUserId(user_id);

            // 企业不存在 添加企业
            Enterprise enterprise_new = enterpriseService.insert(enterprise);
            // 添加企业之后校验
            if (EmptyUtils.isEnterpriseEmpty(enterprise_new)) {
                return ReturnOperator.createResultMsg("", ServerStatus.DATA_INSERT_ERR, ServerStatus.ERROR,
                        new ArrayList<>(), emptyObject, HttpStatus.OK);
            }

            // 企业id 添加到 项目基本情况
            projectBaseInfo.setEnId(enterprise_new.getId());
            // 设置关联企业用户id
            projectBaseInfo.setEnUserId(user_id);

            // 添加项目基本情况
            ProjectBaseInfo projectBaseInfo_new = projectBaseInfoService.insert(projectBaseInfo);
            // 添加数据后的校验
            if (!EmptyUtils.isProjectBaseInfoEmpty(projectBaseInfo_new)) {
                return ReturnOperator.createResultMsg("", ServerStatus.DATA_INSERT_ERR, ServerStatus.ERROR,
                        new ArrayList<>(), emptyObject, HttpStatus.OK);
            }

            // 项目基本情况id  添加上传票据
            bill.setProjectBaseInfoId(projectBaseInfo_new.getId());
            // 添加关联企业用户
            bill.setEnUserId(user_id);

            // 插入票据
            billService.insert(bill);

            // 项目基本情况id 添加到 项目要件
            projectImportantDocument.setProjectBaseInfoId(projectBaseInfo_new.getId());
            // 添加关联企业用户
            projectImportantDocument.setEnUserId(user_id);

            // 插入项目要件
            ProjectImportantDocument projectImportantDocument_new = projectImportantDocumentService.insert(projectImportantDocument);
            // 添加数据后的校验
            if (!EmptyUtils.isProjectImportantDocumentEmpty(projectImportantDocument_new)) {
                return ReturnOperator.createResultMsg("", ServerStatus.DATA_INSERT_ERR, ServerStatus.ERROR,
                        new ArrayList<>(), emptyObject, HttpStatus.OK);
            }

            // 项目基本情况id 添加到 产品表关联id
            product.setProjectBaseInfoId(projectBaseInfo_new.getId());
            // 添加关联企业用户
            product.setEnUserId(user_id);

            // 添加产品
            Product product_new = productService.insert(product);
            // 添加数据后的校验
            if (!EmptyUtils.isProductEmpty(product_new)) {
                return ReturnOperator.createResultMsg("", ServerStatus.DATA_INSERT_ERR, ServerStatus.ERROR,
                        new ArrayList<>(), emptyObject, HttpStatus.OK);
            }

            // 将 产品id 关联到产品月能耗 上的Productid
            productMonthEnergyconsumption.setProductId(product_new.getId());
            // 添加关联企业用户
            productMonthEnergyconsumption.setEnUserId(user_id);

            // 添加产品月能耗记录
            ProductMonthEnergyconsumption productMonthEnergyconsumption_new = productMonthEnergyconsumptionService.insert(productMonthEnergyconsumption);
            // 添加数据后的校验
            if (!EmptyUtils.isProductMonthEnergyconsumptionEmpty(productMonthEnergyconsumption_new)) {
                return ReturnOperator.createResultMsg("", ServerStatus.DATA_INSERT_ERR, ServerStatus.ERROR,
                        new ArrayList<>(), emptyObject, HttpStatus.OK);
            }
            // 返回数据
            return ReturnOperator.createResultMsg(ServerStatus.DATA_INSERT_SUCCESS, "", ServerStatus.OK,
                    new ArrayList<>(), new Boolean(true), HttpStatus.OK);
        }

        /**
         * 管理员的情况下
         */
        // 企业不存在 添加企业
        Enterprise enterprise_new = enterpriseService.insert(enterprise);
        // 添加企业之后校验
        if (EmptyUtils.isEnterpriseEmpty(enterprise_new)) {
            return ReturnOperator.createResultMsg("", ServerStatus.DATA_INSERT_ERR, ServerStatus.ERROR,
                    new ArrayList<>(), emptyObject, HttpStatus.OK);
        }

        /**
         * 临时文件判断
         */
        // 取到resources/static/tempupload/下路径
        String resources_tmp = Thread.currentThread().getContextClassLoader().getResource("").getPath() + "/static/tempupload";
        // 目标路径
        String resources = Thread.currentThread().getContextClassLoader().getResource("").getPath() + "/static/upload";

        // 构建临时文件对象
        File file = new File(resources_tmp + tempfilename);
        // 判断临时上传的文件不存在情况下
        if (!file.exists()) {
            return ReturnOperator.createResultMsg("", "文件临时上传已过期,请在1分钟之内处理", ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }


        /**
         * 构建日期目录 将临时文件移动到日期目录内
         */
        // 设置日期时间格式
        SimpleDateFormat datef = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat timef = new SimpleDateFormat("HH:mm");
        // 获取当前系统时间对象
        Date date = new Date();
        // 拼接 文件夹日期时间名称  例如:2021-6-25-15-55
        String new_path = "/" + datef.format(date) + "-" + timef.format(date) + "/";
        // 构建文件夹对象
        File upload_folder = new File(resources + new_path);
        // 判断文件夹是否存在
        if (!upload_folder.exists()) {
            // 不存在则创建文件夹
            upload_folder.mkdirs();
        }
        // 构造目标存在文件对象   resources目录+企业id+当前系统日期时间+目标文件名
        File upload_file = new File(resources + "/" + enterprise_new.getId() + new_path + tempfilename);
        try{
            // 将临时文件移动到目标存放位置
            FileUtils.moveFile(file, upload_file);
        }catch (IOException e) {
            e.printStackTrace();
        }
        // 保存文件相对路径位置到对象中
        enterprise_new.setLicenseImg("/" + enterprise_new.getId() + new_path + tempfilename);

        // 将营业执照更新到数据库
        Enterprise enterprise_update = enterpriseService.update(enterprise_new);

        // 判断数据插入是否成功
        if(!EmptyUtils.isEnterpriseEmpty(enterprise_update)) {
            return ReturnOperator.createResultMsg("", ServerStatus.DATA_UPDATE_ERR, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }



        /**
         *  项目基本情况操作
         */
        // 企业id 添加到 项目基本情况
        projectBaseInfo.setEnId(enterprise_new.getId());

        // 添加项目基本情况
        ProjectBaseInfo projectBaseInfo_new = projectBaseInfoService.insert(projectBaseInfo);
        // 添加数据后的校验
        if (!EmptyUtils.isProjectBaseInfoEmpty(projectBaseInfo_new)) {
            return ReturnOperator.createResultMsg("", ServerStatus.DATA_INSERT_ERR, ServerStatus.ERROR,
                    new ArrayList<>(), emptyObject, HttpStatus.OK);
        }

        /**
         * 票据上传 临时文件操作
         */
        File[] files = null;
        for (int i = 0; i < tempfilenames.length; i++) {
            // 构建临时文件对象
            files[i] = new File(resources_tmp + tempfilenames[i]);

            // 判断临时上传的文件不存在情况下
            if (!files[i].exists()) {
                return ReturnOperator.createResultMsg("", "文件临时上传已过期,请在1分钟之内处理", ServerStatus.ERROR,
                        new ArrayList(), emptyObject, HttpStatus.OK);
            }
        }

        /**
         * 票据上传 目标目录不存在则创建
         * 将临时文件夹内的文件移动到日期目标目录
         */
        // 构建文件夹对象
        File upload_folders = new File(resources + new_path);
        // 判断文件夹是否存在
        if (!upload_folders.exists()) {
            // 不存在则创建文件夹
            upload_folders.mkdirs();
        }

        // 将临时文件夹内的文件移动到日期目录内
        for (int i = 0; i<tempfilenames.length; i++) {
            // 构造目标存在文件对象   resources目录+企业id+当前系统日期时间+目标文件名
            File upload_files = new File(resources + "/" + projectBaseInfo_new.getEnId() + new_path + tempfilenames[i]);
            try {
                // 将临时文件移动到目标存放位置
                FileUtils.moveFile(files[i], upload_files);
            } catch (IOException e) {
                e.printStackTrace();
            }

            // 将项目基本信息id设置到票据对象中
            bill.setProjectBaseInfoId(projectBaseInfo_new.getId());

            // 保存文件相对路径位置到对象中
            bill.setFilePath("/" + projectBaseInfo_new.getId() + new_path + tempfilenames[i]);
            // 当前票据添加到数据库
            Bill bill_new = billService.insert(bill);
        }


        /**
         * 项目要件操作
         */
        // 项目基本情况id 添加到 项目要件
        projectImportantDocument.setProjectBaseInfoId(projectBaseInfo_new.getId());

        // 插入项目要件
        ProjectImportantDocument projectImportantDocument_new = projectImportantDocumentService.insert(projectImportantDocument);
        // 添加数据后的校验
        if (!EmptyUtils.isProjectImportantDocumentEmpty(projectImportantDocument_new)) {
            return ReturnOperator.createResultMsg("", ServerStatus.DATA_INSERT_ERR, ServerStatus.ERROR,
                    new ArrayList<>(), emptyObject, HttpStatus.OK);
        }

        // 项目基本情况id 添加到 产品关联的 项目基本情况id上
        product.setProjectBaseInfoId(projectBaseInfo_new.getId());

        // 添加产品
        Product product_new = productService.insert(product);
        // 添加数据后的校验
        if (!EmptyUtils.isProductEmpty(product_new)) {
            return ReturnOperator.createResultMsg("", ServerStatus.DATA_INSERT_ERR, ServerStatus.ERROR,
                    new ArrayList<>(), emptyObject, HttpStatus.OK);
        }

        // 将 产品id 添加到 产品月能耗记录的关联id上
        productMonthEnergyconsumption.setProductId(product_new.getId());

        // 添加产品月能耗 记录
        ProductMonthEnergyconsumption productMonthEnergyconsumption_new = productMonthEnergyconsumptionService.insert(productMonthEnergyconsumption);
        // 添加数据后的校验
        if (!EmptyUtils.isProductMonthEnergyconsumptionEmpty(productMonthEnergyconsumption_new)) {
            return ReturnOperator.createResultMsg("", ServerStatus.DATA_INSERT_ERR, ServerStatus.ERROR,
                    new ArrayList<>(), emptyObject, HttpStatus.OK);
        }
        // 返回数据
        return ReturnOperator.createResultMsg(ServerStatus.DATA_INSERT_SUCCESS, "", ServerStatus.OK,
                new ArrayList<>(), new Boolean(true), HttpStatus.OK);

    }


    /**
     * 企业文件图片上传
     * @param file  文件对象
     * @return
     */
    @PostMapping("/uploadFile")
    @ApiOperation(value = "级联添加中企业营业执照上传",produces = "application/json",consumes = "multipart/form-data")
    @ApiImplicitParam(name = "file", value = "文件对象",required = true,dataType = "Part",paramType = "Part",dataTypeClass = Part.class)
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public ResponseEntity<ResultMsg> upFileLoad(@ApiIgnore Part file) {

        // 上传文件校验
        if(!EmptyUtils.isNotFile(file)) {
            return ReturnOperator.createResultMsg("", ServerStatus.FILE_UPLOAD_ERR, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        try{
            // 写入文件 实际写入到application.yml中配置的 classpath下的tempupload下
            // 也就是main目录下的resources下的static/tempload 存放临时位置
            tempfilename = file.getSubmittedFileName();
            file.write(tempfilename);
        }catch (Exception e) {
            e.printStackTrace();
        }

        // 返回数据
        return ReturnOperator.createResultMsg(ServerStatus.FILE_UPLOAD_SUCCESS, "", ServerStatus.OK,
                new ArrayList(), new Boolean(true), HttpStatus.OK);
    }


    /**
     * 票据多文件图片上传
     * @param files  文件数组对象
     * @return
     */
    @PostMapping("/uploadFiles")
    @ApiOperation(value = "级联添加中票据多文件上传",produces = "application/json",consumes = "multipart/form-data")
    @ApiImplicitParam(name = "files", value = "文件对象数组",required = true,dataType = "Part",paramType = "Part[]",dataTypeClass = Part.class)
    @ApiResponses({
            @ApiResponse(code = 200, message = "表明该请求被成功地完成,所请求的资源发送到客户端"),
            @ApiResponse(code = 401, message = "请求要求身份验证,常见于需要登录而用户未登录的情况"),
            @ApiResponse(code = 403, message = "服务器拒绝请求,常见于机密信息或复制其它登录而用户未登录的情况"),
            @ApiResponse(code = 404, message = "服务器无法取得所请求的网页,请求资源不存在"),
            @ApiResponse(code = 500, message = "服务器内部错误")
    })
    public ResponseEntity<ResultMsg> upFileLoads(Part[] files) {

        // 上传文件校验
        if(!EmptyUtils.isNotFiles(files)) {
            return ReturnOperator.createResultMsg("", ServerStatus.FILE_UPLOAD_ERR, ServerStatus.ERROR,
                    new ArrayList(), emptyObject, HttpStatus.OK);
        }

        try{
            // 写入文件 实际写入到application.yml中配置的 classpath下的tempupload下
            // 也就是main目录下的resources下的static/tempload 存放临时位置
            // 循环写文件到临时目录下
            for(int i = 0; i < files.length; i++){
                tempfilenames[i] = files[i].getSubmittedFileName();
                files[i].write(tempfilenames[i]);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }

        // 返回数据
        return ReturnOperator.createResultMsg(ServerStatus.FILE_UPLOAD_SUCCESS, "", ServerStatus.OK,
                new ArrayList(), new Boolean(true), HttpStatus.OK);
    }

}
